#include "Instrument.h"
#include "InstrumentFactory.h"
#include "Note.h"
#include "Audio.h"
#include "AudioFactory.h"
#include "Mixer.h"
#include "DefaultMixer.h"
#include "FilterFactory.h"
#include "SampleFactory.h"
#include "Slide.h"
#include <iostream>
#include <fstream>
#include <sstream>

using namespace libtrckr;
using namespace std;



int main(){
	string atype[4] = {"Wav","Jack", "Alsa", "Arts"};
	Instrument *i = InstrumentFactory::CreateInstrumentFromFile("./format.ltr");
	cout << "Vérification des Audios " << endl;
	Audio *a;	
	Mixer *m = new DefaultMixer();
	m->tracks(1);
	m->length(1024);
	int working=-1;
	for(uint j=0;j<4;j++){
		cout << "Type : " << atype[j] << endl;
		a = AudioFactory::getNewAudio(atype[j]);
		a->param("filename","test.wav");
		if(a != NULL){
			a->channels(2);
			a->bitrate(44100);
			a->open();
			if(a->state()!= Audio::OPEN){
				cerr << "Impossible d'ouvrir le playback" << endl;
			}else{
				i->addNote("A-4",Duration::BLANCHE,false,10,0,0);
				Buffer b=i->play(1024);
				m->Append(b,0,50,0);
				a->append(m->Mixed());
				while(!i->end()){
					i->play(b);
					m->Append(b,0,50,0);
					a->append(m->Mixed());
				}
			sleep(1);
			a->close();
			working=j;
			cout << "Ok" << endl;
			}
			delete a;
			
		}
	}

	sleep(4);

	cout << "Vérification des Filtres (sortie avec " << atype[working] << ")" << endl;
	string path[]={"./",""};
	FilterFactory::init(path,1);
	Sample *s = SampleFactory::newSample("dist.wav");
	string afiltre[] = {"FilterLP","FilterHP", "FilterEqualizer","FilterOctave","FilterFlanging","FilterCompressor","FilterClipping"};
	Buffer b(1024);
	Buffer b2;
/*	DynArray<int> conf;

	a = AudioFactory::getNewAudio(atype[working]);
	a->param("filename","test.wav");
	a->channels(2);
	a->bitrate(44100);
	a->open();
	if(a->state()!= Audio::OPEN)
		exit(1);



	for(uint j=0;j<7;j++){
		cout << "Filtre : " << afiltre[j] << endl;
		Filter *f=FilterFactory::loadNewFilter(afiltre[j]);
		if(j==0 || j==1){
			conf=DynArray<int>(3,0);
			conf[0]=300;
			conf[1]=22050;
			conf[2]=4;
		}else if(j==2){
			conf=DynArray<int>(10,0);
			conf[0]=8;
			conf[1]=0;
			conf[2]=50;
			conf[3]=200;
			conf[4]=1000;
			conf[5]=100;
			conf[6]=5000;
			conf[7]=-100;
			conf[8]=10000;
			conf[9]=44100;
		}else if(j==3){
			conf = DynArray<int>(2,0);
			conf[0]=1;
			conf[1]=-2;
		}else if(j==4){
			conf = DynArray<int>(3,0);
			conf[0]=20;
			conf[1]=-2;
			conf[2]=44100;
		}else if(j==5){
			conf = DynArray<int>( 7,0);
			conf[0]=2;
			conf[1]=1;
			conf[2]=1;
			conf[3]=-10*100;
			conf[4]=4;
			conf[5]=1;
			conf[6]=44100;
		}else if(j==6){
			conf = DynArray<int>( 11,0);
			conf[0]=6;
			conf[1]=30;
			conf[2]=500;
			conf[3]=500;
			conf[4]=0;
			conf[5]=1500;
			conf[6]=200;
			conf[7]=200;
			conf[8]=-10;
			conf[9]=300;
			conf[10]=44100;
		}
		f->Tune(conf);
		f->Init();
		while(!s->isEOF()){
			b << *s << *f;
			m->Append(b,0,50,0);
			b2 = m->Mixed();
			while(a->append(b2)==0){
				usleep(10000);
			}
			b.flush();
		}
	}
	
	a->close();
/*	Filter *f1 = FilterFactory::loadNewFilter("Equalizer");
	i->addFilter(f1,-1);
	i->ApplyFilters(i->play(b));*/
	/*Converter c(0.5,1024);
	i->addNote("A-4",Duration::BLANCHE,false,10,0,0);
	Buffer b3(1024 );
	c.outputsize(1024);
	while(!i->end()){
		i->play(b);
		int ret = c.convert(b,b3);
		if(ret!=0){
			for(uint i=0;i<b.size();i++)
				cout << i << " : " << b[i] << endl;

			for(uint i=0;i<b3.size();i++)
				cout << i << ": " << b3[i] << endl;
		}
	}*/
	DynArray<PlayingEffect*> d(1,NULL);
	Slide sl;
	d[0]=&sl;
	DynArray<double> conf(2,0.0);
	string a4("A-4");
	Note n(a4,Duration::BLANCHE,false);
	conf[0]=0.5;
	conf[1]=n.sampleLength();
	d[0]->Tune(conf);
	cout << "Effects : " << &d << std::endl;
	i->addNote("A-4",Duration::BLANCHE,false,10,0,0,&d);
	while(!i->end()){
		i->play(b);
	}
	delete i;
	delete m;
	/*Instrument *i = new InstrumentPerc();
	string tun[3] = {"A0","B0",""};
	string att[3] = {"med","tip",""};
	i->setTuning(tun);
	i->setAttack(att);
	i->setNote("C#5","dist.wav",1.,0,1,1);
	i->addNote("C#5",Duration::BLANCHE,false,10,1,1);
	string **attack = i->getAttacks();
	uint8_t j=0;
	while(attack[j]!=0){
		std::cout << *attack[j] << std::endl;
		j++;
	}
	Buffer b=i->play(1024);
	i->letRing(true);
	i->play(b);
	std::cout << "is it the end ?" << i->end() << std::endl;
	delete i;*/
}

